package com.smartstate.dataManagement.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smartstate.dataManagement.dto.PageDTO;
import com.smartstate.dataManagement.entity.*;
import com.smartstate.dataManagement.eunm.CommonEunm;
import com.smartstate.dataManagement.mapper.PermissionMapper;
import com.smartstate.dataManagement.mapper.RoleMapper;
import com.smartstate.dataManagement.mapper.UserMapper;
import com.smartstate.dataManagement.service.RoleService;
import com.smartstate.dataManagement.util.DateTimeUtil;
import com.smartstate.dataManagement.util.StringUtils;
import com.smartstate.dataManagement.util.UserUtils;
import com.smartstate.dataManagement.util.WrapperUtil;
import com.smartstate.dataManagement.util.eunm.RoleEnum;
import com.smartstate.dataManagement.vo.ResultCode;
import com.smartstate.dataManagement.vo.ResultVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

@Transactional
@Service
@Slf4j
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private PermissionMapper permissionMapper;

    @Resource
    private TokenStore tokenStore;

    @Override
    public Page<Role> queryAllPageByDTO(PageDTO pageDTO) {
        //创建查询语句包装器和分页查询表对象
        Page<Role> page = new Page(pageDTO.getPage(), pageDTO.getSize());
        //根据DTO注解封装查询语句
        Role dto = (Role) pageDTO.getDto();
        QueryWrapper<Role> wrapper = WrapperUtil.convertQuery(dto, Role.class);
        if(null != dto){
            if(StringUtils.isNotBlank(dto.getRoleName())){
                wrapper.like("ROLE_NAME",dto.getRoleName());
            }
            if(StringUtils.isNotBlank(dto.getState())){
                wrapper.eq("state",dto.getState());
            }
        }
        wrapper.orderByDesc(CommonEunm.CREATETIME.getValue());
        //返回分页查询结果
        return baseMapper.selectPage(page, wrapper);
    }

    @Override
    public Role getRoleByName(String roleName) {
        return roleMapper.getRoleByName(roleName);
    }

    @Override
    public Role getRoleByUserId(String userId) {
        return baseMapper.getRoleByUserId(userId);
    }

    @Override
    public Role getByRoleId(String id) {
        return roleMapper.getByRoleId(id);
    }

    @Override
    public List<Role> getEnableAll() {
        return  roleMapper.getEnableAll();
    }

    @Override
    public Page<Role> getRoleByNameAndStatus(PageDTO<Role> pageDTO) {
        //创建查询语句包装器和分页查询表对象
        Page<Role> page = new Page(pageDTO.getPage(), pageDTO.getSize());
        //根据DTO注解封装查询语句
        List<Role> roles=roleMapper.getRoleByNameAndStatus(pageDTO.getDto().getRoleName(),pageDTO.getDto().getState().toString());
        page.setRecords(roles);
        //返回分页查询结果
        return page;
    }

    @Override
    public Boolean add(Role item) {
        String id = IdUtil.simpleUUID();
        item.setId(id);
        return this.save(item);
    }

    @Override
    public ResultVO<String> addRole(String roleName, String note, List<String> ids) {
        // 根据用户ID获取用户
        User user=userMapper.getUser(UserUtils.getLoginUser().getId());
        if(StringUtils.isNotBlank(roleName)){
            // 判断角色为空时，允许添加,不允许添加相同角色, 一个角色对应很多权限
            Boolean result=false;
            if(null==roleMapper.getRoleByName(roleName)){
                Role role=new Role();
                role.setId(IdUtil.objectId());
                role.setState(CommonEunm.STATUS_ON.getValue());
                role.setRoleName(roleName);
                role.setCreateTime(new Date());
                role.setNote(note);
                role.setCreateUser(user.getNickname());
                List<RolePermission> rolePermissions=new ArrayList<>();
                if(ids.size()>0) {
                    for (String id : ids) {
                        RolePermission rolePermission = new RolePermission();
                        rolePermission.setId(IdUtil.objectId());
                        rolePermission.setRoleId(role.getId());
                        rolePermission.setPermId(id);
                        rolePermission.setRoleType(RoleEnum.ROLETYPE_ONE.getValue());
                        rolePermissions.add(rolePermission);
                    }
                }
//            //写入角色， 批量写入权限，角色-权限映射关系
                if(ids.size()<1){
                    if(roleMapper.addRole(role)>0){
                        return  ResultVO.ok("success");
                    }
                }
                if(ids.size()>0){
                    if(roleMapper.addRole(role)>0  && roleMapper.addRoleAndPermissions(rolePermissions)>0) {
                        return ResultVO.ok("success");
                    }
                }

            }
            return  ResultVO.ok("200","该角色名已经存在，不能重复添加");
        }
        return  ResultVO.fail("参数缺失, 请输入参数");
    }

    @Override
    @Transactional
    public ResultVO<String> updatePermById(String roleId, String roleName,String note,List<String> ids) {
        // 根据ID获取当前用户的值
        User user=userMapper.getUser(UserUtils.getLoginUser().getId());
        if(StringUtils.isNotBlank(roleId)) {
            Role role = roleMapper.getByRoleId(roleId);
            role.setRoleName(roleName);
            role.setNote(note);
            role.setUpdateUser(user.getNickname());
            role.setUpdateTime(new Date());
            Boolean result = false;
            List<RolePermission> rolePermissions = new ArrayList<>();
            // 先删除 ， 在新增，
            if (ids.size() > 0) {
                for (String permId : ids) {
                    RolePermission rolePermission = new RolePermission();
                    rolePermission.setId(IdUtil.randomUUID());
                    rolePermission.setRoleId(role.getId());
                    rolePermission.setPermId(permId);
                    rolePermissions.add(rolePermission);
                }
            }
            List<RolePermission> rolePerms=userMapper.getRoleByUserIdSingle(role.getId());

            if(rolePerms.size()>0) {
                if (roleMapper.delByRoleId(role.getId()) > 0) {
                    if (ids.size() > 0) {
                        if (roleMapper.updateById(role) > 0 && roleMapper.addRoleAndPermissions(rolePermissions) > 0) {
                            return ResultVO.ok();
                        }
                        return ResultVO.fail("更新失败");
                    }
                    if (ids.size() < 1) {
                        if (roleMapper.updateById(role) > 0) {
                            return ResultVO.ok();
                        }
                        return ResultVO.fail("更新失败");
                    }
                }
            }
            else{
                if (ids.size() > 0) {
                    if (roleMapper.updateById(role) > 0 && roleMapper.addRoleAndPermissions(rolePermissions) > 0) {
                        return ResultVO.ok();
                    }
                    return ResultVO.fail("更新失败");
                }
                if (ids.size() < 1) {
                    if (roleMapper.updateById(role) > 0) {
                        return ResultVO.ok();
                    }
                    return ResultVO.fail("更新失败");
                }
            }
        }
        return  ResultVO.fail("参数缺失， 请输入参数");
    }

    @Override
    public ResultVO<ResultCode> delRoleByID(String id) {
        Boolean result=false;
        // 根据角色查询用户（角色绑定了用户就不能删除，否则可以删除）
        List<User>  users=roleMapper.getUserByRoleIde(id);
        if(users.size()>0){
            return  ResultVO.fail("该角色绑定用户，不能删除");
        }
        // 根据角色ID获取权限ID， 删除角色， 权限， 角色——权限
        List<String> permIDs=roleMapper.getPermsByRoleId(id);
        if(permIDs.size()>0){
            // 根据角色ID 删除角色-取消权限映射数据关系 ,  根据角色ID删除角色， 根据权限ID 删除权限数据
            if(roleMapper.delRoleAndPerms(id)>0 && roleMapper.delRoleById(id)>0){
                return  ResultVO.ok(ResultCode.SUCCESS);
            }
            return ResultVO.fail(ResultCode.OPERATION_INVALID.getMessage());
        }
        else{
            if(roleMapper.delRoleById(id)>0){
               return ResultVO.ok(ResultCode.SUCCESS);
            }
            return  ResultVO.fail(ResultCode.OPERATION_INVALID.getMessage());

        }
    }


    @Override
    public Boolean delBatchRoleByID(List<String> ids) {
        // 根据角色ID集合 获取对应权限ID集合（ 一个角色对应着多个权限）
        List<String>  permIds=roleMapper.getRolePermByroleIDs(ids);
        Boolean result=false;
       // 根据角色ID集合删除 角色——权限映射关系数据
        if(roleMapper.batchDelRoleAndPerm(ids)>0 && roleMapper.delRolesByIDs(ids)>0 &&  permissionMapper.delBatchByIDs(permIds)>0 ){
            result=true;
        }
        return  result;
    }

    @Override
    public List<Role> getRoleLikeName(String roleName) {
        return  roleMapper.getRoleLikeName(roleName,CommonEunm.STATUS_ON.getValue());
    }

    @Override
    @Transactional
    public ResultVO<ResultCode> updateByRoleID(Role role) {
        if(null !=role) {
            // 根据ID获取角色
            Role role1 = roleMapper.getByRoleId(role.getId());
            if (null == role1) {
                return ResultVO.fail(ResultCode.RESOURCE_NOT_EXISTS.getMessage());
            }
            role.setUpdateUser(UserUtils.getLoginUser().getId());
            role.setUpdateTime(new Date());
            // 获取 绑定该角色的用户的token
            List<TokenData> tokenDatas = roleMapper.getTokenById(role.getId(), CommonEunm.STATUS_ON.getValue());
            // 状态值不为空 ，则根据是否（ 0 是注销， 1 是启用）
            if (StringUtils.isNotBlank(role.getState()) &&  role.getState().equals(CommonEunm.STATUS_OFF.getValue())) {
                // 更新角色信息
                if (roleMapper.updateById(role) > 0) {
                    //如果该角色更用户有关联
                    if (userMapper.getUserAndRoleByRoleID(role.getId()) > 0) {
                    //关联的用户需要跟着禁用（在删除相关的权限信息）
                    if (userMapper.updateStates(role.getId(), CommonEunm.STATUS_OFF.getValue()) > 0) {
                        log.info(" ceshcehsi ");
                        // 注销token
                        if (tokenDatas.size() > 0) {
                            for (TokenData tokenData : tokenDatas) {
                                log.info("tokenData:" + new String(tokenData.getToken()));
                                // 根据token获取用户信息
                                String tokenValue = new String(tokenData.getToken()).replace(OAuth2AccessToken.BEARER_TYPE, org.apache.commons.lang3.StringUtils.EMPTY).trim();
                                try {
                                    OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
                                    tokenStore.removeAccessToken(accessToken);
                                    OAuth2RefreshToken refreshToken = accessToken.getRefreshToken();
                                    tokenStore.removeRefreshToken(refreshToken);
                                } catch (NullPointerException e) {
                                    log.info("注销的token已经失效，没法继续失效");
                                } finally {
                                    // 注销后的token 需要修改标记生效标记
                                    userMapper.updateTokenByList(tokenDatas, CommonEunm.STATUS_OFF.getValue());
                                    // 删除该用户关联的角色
//                                roleMapper.delUserByRoleId(role.getId());
                                }
                            }
                        }
                        return ResultVO.ok(ResultCode.SUCCESS);
                    }
                    return ResultVO.fail(ResultCode.OPERATION_INVALID.getMessage());
                }
                else {
                        return ResultVO.ok(ResultCode.SUCCESS);
                    }
                }
                return ResultVO.fail(ResultCode.OPERATION_INVALID.getMessage());
            } else {// 启用角色(state=1)
                if (roleMapper.updateById(role) > 0) {
                    // 启用角色， 关联的用户需要 也需要启用
                    if(StringUtils.isNotBlank(role.getState())  &&  role.getState().equals(CommonEunm.STATUS_ON.getValue())){
                        // 先判断该角色是否有跟用户关联， 有的话， 角色很用户一起启用， 否则只启用角色
                        if(userMapper.getUserAndRoleByRoleID(role.getId())>0){
                            //关联的用户需要跟着启用（在删除相关的权限信息）
                            if(userMapper.updateStates(role.getId(),CommonEunm.STATUS_ON.getValue())>0){
                                return ResultVO.ok(ResultCode.SUCCESS);
                            }
                        }
                        else{// 只更新角色，不更新用户， 因为该角色还没有关联用户
                            if(roleMapper.updateStateByID(role.getId(),role.getState())>0){
                                return ResultVO.ok(ResultCode.SUCCESS);
                            }
                        }
                    }
                }
            }
            return ResultVO.fail(ResultCode.OPERATION_INVALID.getMessage());
        }
        return  ResultVO.fail(ResultCode.NOT_BLANK.getMessage());
    }
}
